package com.study.reflect.beanInfo;

import com.study.entity.Person;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author HBZ
 * @description bean和map互转
 * @date 2021/10/13 10:49
 */
public class BeanMapUtil {
    /**
     * javabean转成map
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static Map<String, Object> bean2Map(Object obj) throws Exception {
        Map<String, Object> map = new HashMap<>();
        // 获取person类的BeanInfo对象
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        //获取属性描述器
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {

            //获取属性名
            String key = propertyDescriptor.getName();
            if (key.equals("class")) {
                continue;
            }
            //获取该属性的值
            Method readMethod = propertyDescriptor.getReadMethod();
            // 通过反射来调用Person的定义的getName()方法
            Object value = readMethod.invoke(obj);
            map.put(key, value);
        }
        return map;
    }

    /**
     * 打印map集合
     *
     * @param map
     */
    private static void printMap(Map<String, Object> map) {
        for (Map.Entry<String, Object> m : map.entrySet()) {
            System.out.println(m.getKey() + "=" + m.getValue());
        }
        System.out.println("---------------------------------");
    }


    public static <T> T map2Bean(Map<String, Object> map, Class<T> clazz) throws Exception {
        T obj = clazz.newInstance();
        BeanInfo beanInfo = Introspector.getBeanInfo(clazz);

        //获取属性描述器
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {

            //获取属性名
            String key = propertyDescriptor.getName();
            if (key.equals("class")) {
                continue;
            }
            // 如果map中不存在该属性值或值为null，则不用赋值
            if (null == map.get(key)) {
                continue;
            }
            //获取该属性的值
            Method writeMethod = propertyDescriptor.getWriteMethod();
            // obj赋值
            writeMethod.invoke(obj, map.get(key));
        }
        return obj;
    }

    public static void main(String[] args) throws Exception {
        Person p1 = new Person("liujun", 33);
        Map<String, Object> bean2Map = bean2Map(p1);
        printMap(bean2Map);

        Person p2=map2Bean(bean2Map,Person.class);
        System.out.println(p2);
    }

}
